#include <stdarg.h>
#include <string.h>
#include <math.h>
#include "hxPrintf.h"
#include "stdio.h"

int compareStr1Va(int line,const char str1[],const char*format,va_list va)
{
    char str2[1024];
    hxVSNPrintf(str2,sizeof str2,format,va);
    int cmp=strcmp(str1,str2);
    if(cmp)
    {
        hxPrintf("%3d %s format:%-30s std:%-30s hx:%-30s\n",line,(cmp?"err ":"same"),format,str1,str2);
    }
    return cmp;
}

int compareStr1(int line,const char str1[],const char*format,...)
{
    va_list va;
    va_start(va,format);
    return compareStr1Va(line,str1,format,va);
}

int main()
{
    compareStr1(__LINE__,"0 -128 127","%hhd %hhd %hhd",(int8_t)0,(int8_t)INT8_MIN,(int8_t)INT8_MAX);
    compareStr1(__LINE__,"0 -32768 32767","%hd %hd %hd",(int16_t)0,(int16_t)INT16_MIN,(int16_t)INT16_MAX);
    compareStr1(__LINE__,"0 -2147483648 2147483647","%d %d %d",(int32_t)0,(int32_t)INT32_MIN,(int32_t)INT32_MAX);
    compareStr1(__LINE__,"0 -9223372036854775808 9223372036854775807","%lld %lld %lld",(int64_t)0,(int64_t)INT64_MIN,(int64_t)INT64_MAX);

    compareStr1(__LINE__,"0 255","%hhu %hhu",(uint8_t)0,(uint8_t)UINT8_MAX);
    compareStr1(__LINE__,"0 65535","%hu %hu",(uint16_t)0,(uint16_t)UINT16_MAX);
    compareStr1(__LINE__,"0 4294967295","%u %u",(uint32_t)0,(uint32_t)UINT32_MAX);
    compareStr1(__LINE__,"0 18446744073709551615","%llu %llu",(uint64_t)0,(uint64_t)UINT64_MAX);

    compareStr1(__LINE__,"0 ff","%hhx %hhx",(uint8_t)0,(uint8_t)UINT8_MAX);
    compareStr1(__LINE__,"0 ffff","%hx %hx",(uint16_t)0,(uint16_t)UINT16_MAX);
    compareStr1(__LINE__,"0 ffffffff","%x %x",(uint32_t)0,(uint32_t)UINT32_MAX);
    compareStr1(__LINE__,"0 ffffffffffffffff","%llx %llx",(uint64_t)0,(uint64_t)UINT64_MAX);

    compareStr1(__LINE__,"0 FF","%hhX %hhX",(uint8_t)0,(uint8_t)UINT8_MAX);
    compareStr1(__LINE__,"0 FFFF","%hX %hX",(uint16_t)0,(uint16_t)UINT16_MAX);
    compareStr1(__LINE__,"0 FFFFFFFF","%X %X",(uint32_t)0,(uint32_t)UINT32_MAX);
    compareStr1(__LINE__,"0 FFFFFFFFFFFFFFFF","%llX %llX",(uint64_t)0,(uint64_t)UINT64_MAX);

    compareStr1(__LINE__,"0x0 0xff","%#hhx %#hhx",(uint8_t)0,(uint8_t)UINT8_MAX);
    compareStr1(__LINE__,"0x0 0xffff","%#hx %#hx",(uint16_t)0,(uint16_t)UINT16_MAX);
    compareStr1(__LINE__,"0x0 0xffffffff","%#x %#x",(uint32_t)0,(uint32_t)UINT32_MAX);
    compareStr1(__LINE__,"0x00000000 0xffffffff","%#010x %#010x",(uint32_t)0,(uint32_t)UINT32_MAX);
    compareStr1(__LINE__,"0x0 0xffffffffffffffff","%#llx %#llx",(uint64_t)0,(uint64_t)UINT64_MAX);

    compareStr1(__LINE__,"0X0 0XFF","%#hhX %#hhX",(uint8_t)0,(uint8_t)UINT8_MAX);
    compareStr1(__LINE__,"0X0 0XFFFF","%#hX %#hX",(uint16_t)0,(uint16_t)UINT16_MAX);
    compareStr1(__LINE__,"0X0 0XFFFFFFFF","%#X %#X",(uint32_t)0,(uint32_t)UINT32_MAX);
    compareStr1(__LINE__,"0X0 0XFFFFFFFFFFFFFFFF","%#llX %#llX",(uint64_t)0,(uint64_t)UINT64_MAX);

    compareStr1(__LINE__,"a b","%c %c",'a','b');
    compareStr1(__LINE__,"    a     b","%5c %5c",'a','b');
    compareStr1(__LINE__,"   aa    bb","%5s %5s","aa","bb");
    compareStr1(__LINE__,"aa    bb   ","%-5s %-5s","aa","bb");

    compareStr1(__LINE__,"-000001234","%010d",-1234);
    compareStr1(__LINE__,"     -1234","%10d",-1234);
    compareStr1(__LINE__,"         0","%10d",0);
    compareStr1(__LINE__,"      1234","%10d",1234);
    compareStr1(__LINE__,"1234      ","%-010d",1234);
    compareStr1(__LINE__,"0000001234","%010d",1234);
    compareStr1(__LINE__,"322 -322","%lld %lld",(int64_t)322,(int64_t)-322);

/*
test::sprintf\(buffer\,(.*?),(.*?)\);\n *REQUIRE\(!strcmp\(buffer\,(.*?)\)\);\n
compareStr1($3,$1,$2);
TEST_CASE\(\"(.*?)\"\,\"\[\]\"\)
//$1
*/
    //space flag
    compareStr1(__LINE__," 42","% d",42);
    compareStr1(__LINE__,"-42","% d",-42);
    compareStr1(__LINE__,"   42","% 5d",42);
    compareStr1(__LINE__,"  -42","% 5d",-42);
    compareStr1(__LINE__,"             42","% 15d",42);
    compareStr1(__LINE__,"            -42","% 15d",-42);
    compareStr1(__LINE__,"            -42","% 15d",-42);
    compareStr1(__LINE__,"        -42.987","% 15.3f",-42.987);
    compareStr1(__LINE__,"         42.987","% 15.3f",42.987);
    compareStr1(__LINE__,"Hello testing","% s","Hello testing");
    compareStr1(__LINE__," 1024","% d",1024);
    compareStr1(__LINE__,"-1024","% d",-1024);
    compareStr1(__LINE__," 1024","% i",1024);
    compareStr1(__LINE__,"-1024","% i",-1024);
    compareStr1(__LINE__,"1024","% u",1024);
    compareStr1(__LINE__,"4294966272","% u",4294966272U);
    compareStr1(__LINE__,"1234abcd","% x",305441741);
    compareStr1(__LINE__,"edcb5433","% x",3989525555U);
    compareStr1(__LINE__,"1234ABCD","% X",305441741);
    compareStr1(__LINE__,"EDCB5433","% X",3989525555U);
    compareStr1(__LINE__,"x","% c",'x');
    //+ flag
    compareStr1(__LINE__,"+42","%+d",42);
    compareStr1(__LINE__,"-42","%+d",-42);
    compareStr1(__LINE__,"  +42","%+5d",42);
    compareStr1(__LINE__,"  -42","%+5d",-42);
    compareStr1(__LINE__,"            +42","%+15d",42);
    compareStr1(__LINE__,"            -42","%+15d",-42);
    compareStr1(__LINE__,"Hello testing","%+s","Hello testing");
    compareStr1(__LINE__,"+1024","%+d",1024);
    compareStr1(__LINE__,"-1024","%+d",-1024);
    compareStr1(__LINE__,"+1024","%+i",1024);
    compareStr1(__LINE__,"-1024","%+i",-1024);
    compareStr1(__LINE__,"1024","%+u",1024);
    compareStr1(__LINE__,"4294966272","%+u",4294966272U);
    compareStr1(__LINE__,"1234abcd","%+x",305441741);
    compareStr1(__LINE__,"edcb5433","%+x",3989525555U);
    compareStr1(__LINE__,"1234ABCD","%+X",305441741);
    compareStr1(__LINE__,"EDCB5433","%+X",3989525555U);
    compareStr1(__LINE__,"x","%+c",'x');
    //0 flag
    compareStr1(__LINE__,"42","%0d",42);
    compareStr1(__LINE__,"42","%0ld",42L);
    compareStr1(__LINE__,"-42","%0d",-42);
    compareStr1(__LINE__,"00042","%05d",42);
    compareStr1(__LINE__,"-0042","%05d",-42);
    compareStr1(__LINE__,"000000000000042","%015d",42);
    compareStr1(__LINE__,"-00000000000042","%015d",-42);
    compareStr1(__LINE__,"000000000042.12","%015.2f",42.1234);
    compareStr1(__LINE__,"00000000042.988","%015.3f",42.9876);
    compareStr1(__LINE__,"-00000042.98760","%015.5f",-42.9876);
    //- flag
    compareStr1(__LINE__,"42","%-d",42);
    compareStr1(__LINE__,"-42","%-d",-42);
    compareStr1(__LINE__,"42   ","%-5d",42);
    compareStr1(__LINE__,"-42  ","%-5d",-42);
    compareStr1(__LINE__,"42             ","%-15d",42);
    compareStr1(__LINE__,"-42            ","%-15d",-42);
    compareStr1(__LINE__,"42","%-0d",42);
    compareStr1(__LINE__,"-42","%-0d",-42);
    compareStr1(__LINE__,"42   ","%-05d",42);
    compareStr1(__LINE__,"-42  ","%-05d",-42);
    compareStr1(__LINE__,"42             ","%-015d",42);
    compareStr1(__LINE__,"-42            ","%-015d",-42);
    compareStr1(__LINE__,"42","%0-d",42);
    compareStr1(__LINE__,"-42","%0-d",-42);
    compareStr1(__LINE__,"42   ","%0-5d",42);
    compareStr1(__LINE__,"-42  ","%0-5d",-42);
    compareStr1(__LINE__,"42             ","%0-15d",42);
    compareStr1(__LINE__,"-42            ","%0-15d",-42);

    //# flag
    compareStr1(__LINE__,"0b110","%#b",6);

    //specifier
    compareStr1(__LINE__,"Hello testing","Hello testing");

    compareStr1(__LINE__,"Hello testing","%s","Hello testing");
    compareStr1(__LINE__,"1024","%d",1024);
    compareStr1(__LINE__,"-1024","%d",-1024);
    compareStr1(__LINE__,"1024","%i",1024);
    compareStr1(__LINE__,"-1024","%i",-1024);
    compareStr1(__LINE__,"1024","%u",1024);
    compareStr1(__LINE__,"4294966272","%u",4294966272U);
    compareStr1(__LINE__,"1234abcd","%x",305441741);
    compareStr1(__LINE__,"edcb5433","%x",3989525555U);
    compareStr1(__LINE__,"1234ABCD","%X",305441741);
    compareStr1(__LINE__,"EDCB5433","%X",3989525555U);
    compareStr1(__LINE__,"%","%%",3989525555U);

    //width
    compareStr1(__LINE__,"Hello testing","%1s","Hello testing");
    compareStr1(__LINE__,"1024","%1d",1024);
    compareStr1(__LINE__,"-1024","%1d",-1024);
    compareStr1(__LINE__,"1024","%1i",1024);
    compareStr1(__LINE__,"-1024","%1i",-1024);
    compareStr1(__LINE__,"1024","%1u",1024);
    compareStr1(__LINE__,"4294966272","%1u",4294966272U);
    compareStr1(__LINE__,"1234abcd","%1x",305441741);
    compareStr1(__LINE__,"edcb5433","%1x",3989525555U);
    compareStr1(__LINE__,"1234ABCD","%1X",305441741);
    compareStr1(__LINE__,"EDCB5433","%1X",3989525555U);
    compareStr1(__LINE__,"x","%1c",'x');

    //width 20
    compareStr1(__LINE__,"               Hello","%20s","Hello");
    compareStr1(__LINE__,"                1024","%20d",1024);
    compareStr1(__LINE__,"               -1024","%20d",-1024);
    compareStr1(__LINE__,"                1024","%20i",1024);
    compareStr1(__LINE__,"               -1024","%20i",-1024);
    compareStr1(__LINE__,"                1024","%20u",1024);
    compareStr1(__LINE__,"          4294966272","%20u",4294966272U);
    compareStr1(__LINE__,"            1234abcd","%20x",305441741);
    compareStr1(__LINE__,"            edcb5433","%20x",3989525555U);
    compareStr1(__LINE__,"            1234ABCD","%20X",305441741);
    compareStr1(__LINE__,"            EDCB5433","%20X",3989525555U);
    compareStr1(__LINE__,"                   x","%20c",'x');

    //width *20
    compareStr1(__LINE__,"               Hello","%*s",20,"Hello");
    compareStr1(__LINE__,"                1024","%*d",20,1024);
    compareStr1(__LINE__,"               -1024","%*d",20,-1024);
    compareStr1(__LINE__,"                1024","%*i",20,1024);
    compareStr1(__LINE__,"               -1024","%*i",20,-1024);
    compareStr1(__LINE__,"                1024","%*u",20,1024);
    compareStr1(__LINE__,"          4294966272","%*u",20,4294966272U);
    compareStr1(__LINE__,"            1234abcd","%*x",20,305441741);
    compareStr1(__LINE__,"            edcb5433","%*x",20,3989525555U);
    compareStr1(__LINE__,"            1234ABCD","%*X",20,305441741);
    compareStr1(__LINE__,"            EDCB5433","%*X",20,3989525555U);
    compareStr1(__LINE__,"                   x","%*c",20,'x');

    //width -20
    compareStr1(__LINE__,"Hello               ","%-20s","Hello");
    compareStr1(__LINE__,"1024                ","%-20d",1024);
    compareStr1(__LINE__,"-1024               ","%-20d",-1024);
    compareStr1(__LINE__,"1024                ","%-20i",1024);
    compareStr1(__LINE__,"-1024               ","%-20i",-1024);
    compareStr1(__LINE__,"1024                ","%-20u",1024);
    compareStr1(__LINE__,"1024.1234           ","%-20.4f",1024.1234);
    compareStr1(__LINE__,"4294966272          ","%-20u",4294966272U);
    compareStr1(__LINE__,"1234abcd            ","%-20x",305441741);
    compareStr1(__LINE__,"edcb5433            ","%-20x",3989525555U);
    compareStr1(__LINE__,"1234ABCD            ","%-20X",305441741);
    compareStr1(__LINE__,"EDCB5433            ","%-20X",3989525555U);
    compareStr1(__LINE__,"x                   ","%-20c",'x');
    compareStr1(__LINE__,"|    9| |9 | |    9|","|%5d| |%-2d| |%5d|",9,9,9);
    compareStr1(__LINE__,"|   10| |10| |   10|","|%5d| |%-2d| |%5d|",10,10,10);
    compareStr1(__LINE__,"|    9| |9           | |    9|","|%5d| |%-12d| |%5d|",9,9,9);
    compareStr1(__LINE__,"|   10| |10          | |   10|","|%5d| |%-12d| |%5d|",10,10,10);

    //width 0-20
    compareStr1(__LINE__,"Hello               ","%0-20s","Hello");
    compareStr1(__LINE__,"1024                ","%0-20d",1024);
    compareStr1(__LINE__,"-1024               ","%0-20d",-1024);
    compareStr1(__LINE__,"1024                ","%0-20i",1024);
    compareStr1(__LINE__,"-1024               ","%0-20i",-1024);
    compareStr1(__LINE__,"1024                ","%0-20u",1024);
    compareStr1(__LINE__,"4294966272          ","%0-20u",4294966272U);
    compareStr1(__LINE__,"1234abcd            ","%0-20x",305441741);
    compareStr1(__LINE__,"edcb5433            ","%0-20x",3989525555U);
    compareStr1(__LINE__,"1234ABCD            ","%0-20X",305441741);
    compareStr1(__LINE__,"EDCB5433            ","%0-20X",3989525555U);
    compareStr1(__LINE__,"x                   ","%0-20c",'x');

    //padding 20;
    compareStr1(__LINE__,"00000000000000001024","%020d",1024);
    compareStr1(__LINE__,"-0000000000000001024","%020d",-1024);
    compareStr1(__LINE__,"00000000000000001024","%020i",1024);
    compareStr1(__LINE__,"-0000000000000001024","%020i",-1024);
    compareStr1(__LINE__,"00000000000000001024","%020u",1024);
    compareStr1(__LINE__,"00000000004294966272","%020u",4294966272U);
    compareStr1(__LINE__,"0000000000001234abcd","%020x",305441741);
    compareStr1(__LINE__,"000000000000edcb5433","%020x",3989525555U);
    compareStr1(__LINE__,"0000000000001234ABCD","%020X",305441741);
    compareStr1(__LINE__,"000000000000EDCB5433","%020X",3989525555U);

    //padding #020
    compareStr1(__LINE__,"00000000000000001024","%#020d",1024);
    compareStr1(__LINE__,"-0000000000000001024","%#020d",-1024);
    compareStr1(__LINE__,"00000000000000001024","%#020i",1024);
    compareStr1(__LINE__,"-0000000000000001024","%#020i",-1024);
    compareStr1(__LINE__,"00000000000000001024","%#020u",1024);
    compareStr1(__LINE__,"00000000004294966272","%#020u",4294966272U);
    compareStr1(__LINE__,"0x00000000001234abcd","%#020x",305441741);
    compareStr1(__LINE__,"0x0000000000edcb5433","%#020x",3989525555U);
    compareStr1(__LINE__,"0X00000000001234ABCD","%#020X",305441741);
    compareStr1(__LINE__,"0X0000000000EDCB5433","%#020X",3989525555U);
    //padding #20
    compareStr1(__LINE__,"                1024","%#20d",1024);
    compareStr1(__LINE__,"               -1024","%#20d",-1024);
    compareStr1(__LINE__,"                1024","%#20i",1024);
    compareStr1(__LINE__,"               -1024","%#20i",-1024);
    compareStr1(__LINE__,"                1024","%#20u",1024);
    compareStr1(__LINE__,"          4294966272","%#20u",4294966272U);
    compareStr1(__LINE__,"          0x1234abcd","%#20x",305441741);
    compareStr1(__LINE__,"          0xedcb5433","%#20x",3989525555U);
    compareStr1(__LINE__,"          0X1234ABCD","%#20X",305441741);
    compareStr1(__LINE__,"          0XEDCB5433","%#20X",3989525555U);
    //padding neg numbers
    // space padding
    compareStr1(__LINE__,"-5","% 1d",-5);
    compareStr1(__LINE__,"-5","% 2d",-5);
    compareStr1(__LINE__," -5","% 3d",-5);
    compareStr1(__LINE__,"  -5","% 4d",-5);
    // zero padding
    compareStr1(__LINE__,"-5","%01d",-5);
    compareStr1(__LINE__,"-5","%02d",-5);
    compareStr1(__LINE__,"-05","%03d",-5);
    compareStr1(__LINE__,"-005","%04d",-5);
    //float padding neg numbers
    // space padding
    compareStr1(__LINE__,"-5.0","% 3.1f",-5.);
    compareStr1(__LINE__,"-5.0","% 4.1f",-5.);
    compareStr1(__LINE__," -5.0","% 5.1f",-5.);
    compareStr1(__LINE__,"    -5","% 6.1g",-5.);
    compareStr1(__LINE__,"-5.0e+00","% 6.1e",-5.);
    compareStr1(__LINE__,"  -5.0e+00","% 10.1e",-5.);

    // zero padding
    compareStr1(__LINE__,"-5.0","%03.1f",-5.);
    compareStr1(__LINE__,"-5.0","%04.1f",-5.);
    compareStr1(__LINE__,"-05.0","%05.1f",-5.);
    // zero padding no decimal point
    compareStr1(__LINE__,"-5","%01.0f",-5.);
    compareStr1(__LINE__,"-5","%02.0f",-5.);
    compareStr1(__LINE__,"-05","%03.0f",-5.);
    compareStr1(__LINE__,"-005.0e+00","%010.1e",-5.);
    compareStr1(__LINE__,"-05E+00","%07.0E",-5.);
    compareStr1(__LINE__,"-05","%03.0g",-5.);
    return 0;
}
